package copyengine.network.roomStructure.subMediator
{
	import copyengine.network.roomStructure.CENetworkCommandNotification;
	import copyengine.network.roomStructure.data.CENetworkRoomMediatorWhiteBoard;
	import copyengine.network.roomStructure.executeLayer.CENetworkRoomExecuteHandleNotification;
	import copyengine.utils.debug.CELog;
	import copyengine.utils.tick.GlobalTick;
	
	import org.puremvc.as3.interfaces.INotification;

	public final class CENetworkRoomSubCreateJoinMediator extends CENetworkRoomSubMediatorBasic
	{
		public function CENetworkRoomSubCreateJoinMediator(_whiteBoard:CENetworkRoomMediatorWhiteBoard)
		{
			super(_whiteBoard);
		}

		override public function listNotificationInterests():Array
		{
			return [
				CENetworkCommandNotification.RECEIVE_COMMAND_CREATE_ROOM,
				CENetworkCommandNotification.RECEIVE_COMMAND_JOIN_ROOM,
				CENetworkRoomExecuteHandleNotification.SEND_SOCKET_SERVER_CONNECTED,
				CENetworkRoomExecuteHandleNotification.SEND_RECEIVE_INCOMING_DATA,
				];
		}

		override public function handleNotification(notification:INotification):void
		{
			switch (notification.getName())
			{
				case CENetworkCommandNotification.RECEIVE_COMMAND_CREATE_ROOM:
					doCreateRoom(notification.getBody()["roomName"],
								 notification.getBody()["roomPassword"],
								 notification.getBody()["playerUID"]);
					break;
				case CENetworkCommandNotification.RECEIVE_COMMAND_JOIN_ROOM:
					doJoinRoom(notification.getBody()["roomID"],
							   notification.getBody()["roomPassword"],
							   notification.getBody()["playerUID"]);
					break;
				case CENetworkRoomExecuteHandleNotification.SEND_SOCKET_SERVER_CONNECTED:
					onSocketServerConnected();
					break;
				case CENetworkRoomExecuteHandleNotification.SEND_RECEIVE_INCOMING_DATA:
					onReceiveIncomingData(notification.getBody()["command"],
										  notification.getBody()["commandArg"],
										  notification.getBody()["forwardData"]);
					break;
			}
		}

		//====================
		//==Incoming Data
		//====================

		private function onReceiveIncomingData(_command:uint, _commandArg:Object, _forwardData:Object):void
		{
			switch (_command)
			{
				case CENetworkCommandNotification.S_RESERVE_COMMAND_CREATE_ROOM_RETURN:
					onCreateRoomCallBack(_commandArg);
					break;
				case CENetworkCommandNotification.S_RESERVE_COMMAND_JOIN_ROOM_RETURN:
					onJoinRoomCallBack(_commandArg);
					break;
			}
		}

		//====================
		//==Create Room
		//====================
		/**
		 * 创建房间
		 *
		 * @param _roomName 房间名称
		 * @param _roomPassword 房间密码(null则为空,无密码)
		 * @param _playerUID (建立房间人的UID)
		 */
		private function doCreateRoom(_roomName:String, _roomPassword:String, _playerUID:String):void
		{
			if (!whiteBoard.isDuringCreateRoom)
			{
				whiteBoard.isDuringCreateRoom = true;
				whiteBoard.roomName = _roomName;
				whiteBoard.roomPassword = _roomPassword;
				whiteBoard.playerUID = _playerUID;
				//首先尝试连接Socket
				tryToConnectSocketServer();
			}
		}

		private function onCreateRoomCallBack(_arg:Object):void
		{
			var errorCode:uint = _arg["errCode"];
			var roomID:uint = _arg["roomId"];
			if (errorCode > 0)
			{
				//房间断开连接后的回调
				sendNotification(CENetworkRoomExecuteHandleNotification.RECEIVE_END_CONNECT_SOCKET_SERVER);
			}
			else
			{
				whiteBoard.isDuringCreateRoom = false;
				whiteBoard.isAlreadyInRoom = true;
				whiteBoard.roomID = roomID;
				//需要在下一帧再发送加入房间成功，本帧需要先发送SEND_NEIGHBOUR_STATUS_CHANGE
				//因为上层逻辑会根据加入房间成功or创建房间成功与否进行logic处理，而数据源的守护进程
				//会根据SEND_NEIGHBOUR_STATUS_CHANGE进行数据源的更改
				GlobalTick.instance.callLaterAfterTickCount(doSendCreateRoomSucceed);
			}
		}

		private function doSendCreateRoomSucceed():void
		{
			sendNotification(CENetworkCommandNotification.SEND_CREATE_ROOM_SUCCEED, {roomID:whiteBoard.roomID});
		}

		//=================
		//==Join Room
		//=================
		/**
		 * 加入房间
		 *
		 * @param _roomID  退出房间的ID
		 * @param _roomPassword
		 * @param _playerUID
		 */
		private function doJoinRoom(_roomID:uint, _roomPassword:String, _playerUID:String):void
		{
			if (!whiteBoard.isDuringJoinRoom)
			{
				whiteBoard.isDuringJoinRoom = true;
				whiteBoard.roomID = _roomID;
				whiteBoard.roomPassword = _roomPassword;
				whiteBoard.playerUID = _playerUID;
				//首先尝试连接Socket
				tryToConnectSocketServer();
			}
		}

		private function onJoinRoomCallBack(_arg:Object):void
		{
			var errorCode:uint = _arg["errorCode"];
			if (errorCode > 0)
			{
				sendNotification(CENetworkRoomExecuteHandleNotification.RECEIVE_END_CONNECT_SOCKET_SERVER);
			}
			else
			{
				whiteBoard.isDuringJoinRoom = false;
				whiteBoard.isAlreadyInRoom = true;
				//需要在下一帧再发送加入房间成功，本帧需要先发送SEND_NEIGHBOUR_STATUS_CHANGE
				//因为上层逻辑会根据加入房间成功or创建房间成功与否进行logic处理，而数据源的守护进程
				//会根据SEND_NEIGHBOUR_STATUS_CHANGE进行数据源的更改
				GlobalTick.instance.callLaterAfterTickCount(doSendJoinRoomSucceed);
			}
		}

		private function doSendJoinRoomSucceed():void
		{
			sendNotification(CENetworkCommandNotification.SEND_JOIN_ROOM_SUCCEED, {roomID:whiteBoard.roomID});
		}


		//==========================
		//==Socket Server Connect&Disconnect
		//==========================

		/**
		 *连接房间房间
		 */
		private function tryToConnectSocketServer():void
		{
			sendNotification(CENetworkRoomExecuteHandleNotification.RECEIVE_START_CONNECT_SOCKET_SERVER,
							 {
								 url:whiteBoard.socketURL,
								 prot:whiteBoard.socketProt
							 });
		}

		private function onSocketServerConnected():void
		{
			//创建房间
			if (whiteBoard.isDuringCreateRoom)
			{
				var createRoomCommandArg:Object =
					{
						name:whiteBoard.roomName,
						password:whiteBoard.roomPassword,
						uid:whiteBoard.playerUID
					};
				sendSocketCommand(CENetworkCommandNotification.F_RESERVE_COMMAND_CREATE_ROOM, createRoomCommandArg);
			}
			//加入房间
			else if (whiteBoard.isDuringJoinRoom)
			{
				var joinRoomCommandArg:Object =
					{
						roomID:whiteBoard.roomID,
						password:whiteBoard.roomPassword,
						uid:whiteBoard.playerUID
					};
				sendSocketCommand(CENetworkCommandNotification.F_RESERVE_COMMAND_JOIN_ROOM, joinRoomCommandArg);
			}
			else
			{
				CELog.err("CENetworkRoomSubCreateJoinMediator->onSocketServerConnected but not for create room or join room")
			}
		}

	}
}
